package com.pine.dbant.common.plugin;


import com.alibaba.druid.pool.GetConnectionTimeoutException;
import com.pine.dbant.common.exeception.BusinessException;
import com.pine.dbant.common.model.ConnectionInfo;
import com.pine.dbant.common.model.JdbcMetadataTreeView;
import com.pine.dbant.common.plugin.impl.DefaultJdbcMetadataAnalysis;
import com.pine.dbant.common.plugin.impl.DefaultMetaAnalysisFilter;
import com.pine.dbant.common.plugin.meta.*;
import com.pine.dbant.common.plugin.meta.function.jdbc.*;
import com.pine.dbant.common.store.CacheStore;
import com.pine.sunflower.core.plugin.Configuration;
import com.pine.sunflower.core.utils.Strings;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;

/**
 * @author xiaoyuan
 * @create 2022/11/8 16:53
 **/
@Slf4j
public abstract class AbstractJdbcDatabasePlugin extends DynamicDataSourceDruid implements DatabasePlugin, DynamicDataSource {

    protected Configuration configuration;
    protected CacheStore cacheStore;

    public AbstractJdbcDatabasePlugin(Configuration configuration,CacheStore cacheStore) {
        super(configuration);
        this.configuration = configuration;
        this.cacheStore = cacheStore;
    }

    @Override
    public MetadataAnalysis createMetadataAnalysis(ConnectionInfo connectionInfo) {
        DataSource dataSource = getDataSource(connectionInfo);
        if (dataSource == null) {
            throw new BusinessException("获取数据库连接异常");
        }
        try {
            AbstractJdbcMetadataAnalysis jdbcMetadataAnalysis = new DefaultJdbcMetadataAnalysis();
            jdbcMetadataAnalysis.filter(new DefaultMetaAnalysisFilter())
                    .configuration(this.configuration)
                    .connection(dataSource.getConnection())
                    .connectionInfo(connectionInfo)
                    .cacheStore(cacheStore);
            ((MetadataAnalysisConfig) jdbcMetadataAnalysis).addFunction(Arrays.asList(new
                            CatalogFunction(JdbcMetadataTreeView.CONN.getType()),
                    new CatalogChildrenFunction(JdbcMetadataTreeView.CATALOG.getType()),
                    new TablesFunction(JdbcMetadataTreeView.TABLE_TYPE.getType()),
                    new ViewsFunction(JdbcMetadataTreeView.VIEW_TYPE.getType()),
                    new FunctionsFunction(JdbcMetadataTreeView.FUNCTION_TYPE.getType())));
            functionRegister().register(jdbcMetadataAnalysis);
            return jdbcMetadataAnalysis;
        }catch (GetConnectionTimeoutException e){
             throw new BusinessException(Strings.format("不能连接到服务器[{}]",connectionInfo.getHost()));
        }catch (SQLException e) {
            throw new JdbcMetaAnalysisException("创建分析器失败", e);
        }
    }

    @Override
    public Connector createConnection(ConnectionInfo connectionInfo) {
        DataSource dataSource = getDataSource(connectionInfo);
        if (dataSource == null) {
            throw new BusinessException("获取数据库连接异常");
        }
        try {
            return new JdbcConnector(this.configuration, dataSource.getConnection(), connectionInfo);
        } catch (SQLException e) {
            throw new JdbcException("创建连接器失败", e);
        }
    }


    @Override
    public void doStop() {
        super.doStop();
    }

    @Override
    public void doInit() {
        super.doInit();
    }

    public FunctionRegister functionRegister() {
        return config -> {};
    }
}
